home *** CD-ROM | disk | FTP | other *** search
/ Mac Mania 5 / MacMania 5.toast / / Internet software / NewsWatcher / NW Source / Source / ic.c < prev    next >
Text File  |  1997-01-09  |  28KB  |  897 lines

  1. /*----------------------------------------------------------------------------
  2.  
  3.     ic.c
  4.     
  5.     This module encapsulates the interface to the Internet Config system.
  6.     
  7.     Copyright © 1994-1997, Northwestern University.
  8.  
  9. ----------------------------------------------------------------------------*/
  10.  
  11. #include <stdio.h>
  12. #include <string.h>
  13.  
  14. #include "glob.h"
  15. #include "ic.h"
  16. #include "ICTypes.h"
  17. #include "ICAPI.h"
  18. #include "strutil.h"
  19. #include "fileutil.h"
  20. #include "memutil.h"
  21. #include "apputil.h"
  22. #include "prefs.h"
  23.  
  24.  
  25.  
  26. static ICInstance gInst;
  27. static Boolean gICStartOK = false;
  28.  
  29.  
  30.  
  31. /*----------------------------------------------------------------------------
  32.     MyICGetPref
  33.     
  34.     Get a preference from IC. Same parameters as ICGetPref.
  35. ----------------------------------------------------------------------------*/
  36.  
  37. static pascal ICError MyICGetPref (ICInstance inst, ConstStr255Param key, 
  38.     ICAttr *attr, Ptr buf, long *size)
  39. {
  40.     Str255 keyCopy;        /* word-aligned to avoid crashes on 68000 Macs */
  41.     
  42.     CopyPascalString(keyCopy, (StringPtr)key);
  43.     return ICGetPref(inst, keyCopy, attr, buf, size);
  44. }
  45.  
  46.  
  47.  
  48. /*----------------------------------------------------------------------------
  49.     MyICSetPref
  50.     
  51.     Set a preference to IC. Same parameters as ICSetPref.
  52. ----------------------------------------------------------------------------*/
  53.  
  54. static pascal ICError MyICSetPref (ICInstance inst, ConstStr255Param key, 
  55.     ICAttr attr, Ptr buf, long size)
  56. {
  57.     Str255 keyCopy;        /* word-aligned to avoid crashes on 68000 Macs */
  58.     
  59.     CopyPascalString(keyCopy, (StringPtr)key);
  60.     return ICSetPref(inst, keyCopy, attr, buf, size);
  61. }
  62.  
  63.  
  64.  
  65. /*----------------------------------------------------------------------------
  66.     MyICStart 
  67.     
  68.     Start Internet Config.
  69.     
  70.     Entry:    prefsFileLocated = true if we have found a NewsWatcher Prefs file, 
  71.                 in which case the vRefNum and dirID params are valid, 
  72.                 and we tell Internet Config to search the same folder.
  73.             vRefNum = vol ref num of NewsWatcher Prefs file.
  74.             dirID = dir id of NewsWatcher Prefs file.
  75.             
  76.     This function must be called after locating and reading NewsWatcher's 
  77.     prefs file.
  78. ----------------------------------------------------------------------------*/
  79.  
  80. void MyICStart (Boolean prefsFileLocated, short vRefNum, long dirID)
  81. {
  82.     ICError icErr, icErrCountPref;
  83.     ICDirSpecArray    dirSpecArray;
  84.     long count;
  85.     
  86.     if (gICStartOK) return;
  87.     icErr = ICStart(&gInst, kNewsWatcherSignature);
  88.     if (icErr != noErr) return;
  89.     if (prefsFileLocated) {
  90.         dirSpecArray[0].vRefNum = vRefNum;
  91.         dirSpecArray[0].dirID = dirID;
  92.         icErr = ICFindConfigFile(gInst, 1, (ICDirSpecArrayPtr)&dirSpecArray);
  93.     } else {
  94.         icErr = ICFindConfigFile(gInst, 0, nil);
  95.     }
  96.     if (icErr != noErr) return;
  97.     icErr = ICBegin(gInst, icReadOnlyPerm);
  98.     if (icErr != noErr) return;
  99.     icErrCountPref = ICCountPref(gInst, &count);
  100.     icErr = ICEnd(gInst);
  101.     if (icErr != noErr) return;
  102.     gICStartOK = icErrCountPref == noErr && count > 0;
  103. }
  104.  
  105.  
  106.  
  107. /*----------------------------------------------------------------------------
  108.     MyICStop 
  109.     
  110.     Stop Internet Config.
  111. ----------------------------------------------------------------------------*/
  112.  
  113. void MyICStop (void)
  114. {
  115.     if (gICStartOK) ICStop(gInst);
  116.     gInst = nil;
  117.     gICStartOK = false;
  118. }
  119.  
  120.  
  121.  
  122. /*----------------------------------------------------------------------------
  123.     ScramblePassword 
  124.     
  125.     Apply the Internet Config password scrambling algorithm to a string.
  126.     
  127.     Entry:    str = C-format string.
  128.     
  129.     Exit:    str = scrambled/unscrambled string.
  130. ----------------------------------------------------------------------------*/
  131.  
  132. static void ScramblePassword (char *str)
  133. {
  134.     short i;
  135.  
  136.     for (i = 1; *str; str++, i++) *str ^= 0x55+i;
  137. }
  138.  
  139.  
  140.  
  141. /*----------------------------------------------------------------------------
  142.     ReadCStringFromPString 
  143.     
  144.     Read a C string shared pref from a P string IC pref.
  145.     
  146.     Entry:    maxSize = max size of theString.
  147.             key = IC keyword.
  148.             
  149.     Exit:    theString = pref string as read from IC.
  150. ----------------------------------------------------------------------------*/
  151.  
  152. static void ReadCStringFromPString (char *theString, long maxSize, 
  153.     ConstStr255Param key)
  154. {
  155.     CStr255 str;
  156.     ICError icErr;
  157.     ICAttr attr;
  158.     
  159.     icErr = MyICGetPref(gInst, key, &attr, (Ptr)str, &maxSize);
  160.     if (icErr != noErr) return;
  161.     p2cstr((StringPtr)str);
  162.     if (EqualString(key, kICRealName, true, true)) {
  163.         if (!ValidCString(str, sizeof(gPrefs.fullName), false)) return;
  164.     } else if (EqualString(key, kICOrganization, true, true)) {
  165.         if (!ValidCString(str, sizeof(gPrefs.organization), false)) return;
  166.     } else if (EqualString(key, kICEmail, true, true)) {
  167.         if (!ValidCString(str, sizeof(gPrefs.emailAddress), false)) return;
  168.     } else if (EqualString(key, kICNewsAuthPassword, true, true)) {
  169.         if (!gPrefs.authSavePassword) return;
  170.         ScramblePassword(str);
  171.     }
  172.     strcpy(theString, str);
  173. }
  174.  
  175.  
  176.  
  177. /*----------------------------------------------------------------------------
  178.     ReadPStringFromPString 
  179.     
  180.     Read a P string shared pref from a P string IC pref.
  181.     
  182.     Entry:    maxSize = max size of theString.
  183.             key = IC keyword.
  184.             
  185.     Exit:    theString = pref string as read from IC.
  186. ----------------------------------------------------------------------------*/
  187.  
  188. static void ReadPStringFromPString (StringPtr theString, long maxSize, 
  189.     ConstStr255Param key)
  190. {
  191.     Str255 str;
  192.     ICError icErr;
  193.     ICAttr attr;
  194.     
  195.     icErr = MyICGetPref(gInst, key, &attr, (Ptr)str, &maxSize);
  196.     if (icErr != noErr) return;
  197.     if (EqualString(key, kICNNTPHost, true, true)) {
  198.         if (!ValidPString(str, sizeof(gPrefs.newsServerName), false)) return;
  199.     } else if (EqualString(key, kICSMTPHost, true, true)) {
  200.         if (!ValidPString(str, sizeof(gPrefs.mailServerName), false)) return;
  201.     }    
  202.     CopyPascalString(theString, str);
  203. }
  204.  
  205.  
  206.  
  207. /*----------------------------------------------------------------------------
  208.     ReadCStringFromText 
  209.     
  210.     Read a C string shared pref from a text IC pref.
  211.     
  212.     Entry:    maxSize = max size of theString.
  213.             key = IC keyword.
  214.             
  215.     Exit:    theString = pref string as read from IC.
  216. ----------------------------------------------------------------------------*/
  217.  
  218. static void ReadCStringFromText (char *theString, long maxSize, 
  219.     ConstStr255Param key)
  220. {
  221.     char buf[4096];
  222.     ICError icErr;
  223.     ICAttr attr;
  224.     long size;
  225.     
  226.     size = maxSize - 1;
  227.     icErr = MyICGetPref(gInst, key, &attr, (Ptr)buf, &size);
  228.     if (icErr != noErr) return;
  229.     buf[size] = 0;
  230.     if (EqualString(key, kICSignature, true, true)) {
  231.         if (!ValidCString(buf, sizeof(gPrefs.signature), true)) return;
  232.     }
  233.     BlockMoveData(buf, theString, size+1);
  234. }
  235.  
  236.  
  237.  
  238. /*----------------------------------------------------------------------------
  239.     ReadFolderFromFileSpec 
  240.     
  241.     Read a default folder shared pref from an ICFileSpec IC pref.
  242.     
  243.     Entry:    key = IC keyword.
  244.             
  245.     Exit:    *defaultFolderAlias = handle to default folder alias.
  246. ----------------------------------------------------------------------------*/
  247.  
  248. static void ReadFolderFromFileSpec (AliasHandle *defaultFolderAlias, 
  249.     ConstStr255Param key)
  250. {
  251.     char buf[4096];
  252.     ICError icErr;
  253.     ICAttr attr;
  254.     long size;
  255.     ICFileSpec *p;
  256.     AliasHandle alias;
  257.     OSErr err = noErr;
  258.     
  259.     size = sizeof(buf);
  260.     icErr = MyICGetPref(gInst, key, &attr, (Ptr)buf, &size);
  261.     if (icErr == noErr) {
  262.         p = (ICFileSpec*)buf;
  263.         if (p->alias.aliasSize == 0) {
  264.             err = VolNameAndCreationDateToVRefNum(p->vol_name, p->vol_creation_date,
  265.                 &p->fss.vRefNum);
  266.             if (err != noErr) return;
  267.             err = NewAlias(nil, &p->fss, &alias);
  268.             if (err != noErr) return;
  269.         } else {
  270.             err = MyNewHandle(p->alias.aliasSize, &alias);
  271.             if (err != noErr) return;
  272.             BlockMoveData(&p->alias, *alias, p->alias.aliasSize);
  273.         }
  274.         MyDisposeHandle(*defaultFolderAlias);
  275.         *defaultFolderAlias = alias;
  276.     }
  277. }
  278.  
  279.  
  280.  
  281. /*----------------------------------------------------------------------------
  282.     ReadFontInfo 
  283.     
  284.     Read font info from an ICFontRecord IC pref.
  285.     
  286.     Entry:    key = IC keyword.
  287.             
  288.     Exit:    fontName = font name as read from IC.
  289.             *fontSize = font size as read from IC.
  290. ----------------------------------------------------------------------------*/
  291.  
  292. static void ReadFontInfo (Str255 fontName, short *fontSize, 
  293.     ConstStr255Param key)
  294. {
  295.     ICError icErr;
  296.     ICFontRecord icFontRecord;
  297.     ICAttr attr;
  298.     long size;
  299.  
  300.     size = sizeof(icFontRecord);
  301.     icErr = MyICGetPref(gInst, key, &attr, (Ptr)&icFontRecord, &size);
  302.     if (icErr != noErr) return;
  303.     if (size <= 4 || icFontRecord.size == 0 || *icFontRecord.font == 0) return;
  304.     if (!ValidPString(icFontRecord.font, 255, false)) return;
  305.     CopyPascalString(fontName, icFontRecord.font);
  306.     *fontSize = icFontRecord.size;
  307. }
  308.  
  309.  
  310.  
  311. /*----------------------------------------------------------------------------
  312.     ReadURLHelperInfo 
  313.     
  314.     Read URL Helper info.
  315. ----------------------------------------------------------------------------*/
  316.  
  317. static void ReadURLHelperInfo (void)
  318. {
  319.     ICError icErr;
  320.     Str255 key;
  321.     long i, count;
  322.     short prefixLen, schemeNameLen;
  323.     TURLSchemeName schemeName;
  324.     TURLHelperInfo **h = nil;
  325.     OSErr err = noErr;
  326.     TURLHelperInfo helperInfo;
  327.     TURLHelperInfo *p;
  328.     ICAppSpec icAppSpec;
  329.     ICAttr attr;
  330.     long size, hSize = 0;
  331.     short numHelpers = 0;
  332.     
  333.     err = MyNewHandle(0, &h);
  334.     if (err != noErr) goto exit;
  335.     
  336.     prefixLen = *kICHelper;
  337.     
  338.     icErr = ICCountPref(gInst, &count);
  339.     if (icErr != noErr) goto exit;
  340.     
  341.     for (i = 1; i <= count; i++) {
  342.         icErr = ICGetIndPref(gInst, i, key);
  343.         if (icErr != noErr) goto exit;
  344.         schemeNameLen = *key - prefixLen;
  345.         if (schemeNameLen > 0 && schemeNameLen <= kMaxSchemeNameLen &&
  346.             MyStrNEqual((char*)key+1, (char*)kICHelper+1, prefixLen)) 
  347.         {
  348.             BlockMoveData(key + prefixLen + 1, schemeName, schemeNameLen);
  349.             schemeName[schemeNameLen] = 0;
  350.             if (!MyStrEqual(schemeName, "editor") && !MyStrEqual(schemeName, "mailto") &&
  351.                 !MyStrEqual(schemeName, "nntp") && !MyStrEqual(schemeName, "news"))
  352.             {
  353.                 size = sizeof(icAppSpec);
  354.                 icErr = MyICGetPref(gInst, key, &attr, (Ptr)&icAppSpec, &size);
  355.                 if (icErr != noErr) goto exit;
  356.                 strcpy(helperInfo.schemeName, schemeName);
  357.                 helperInfo.sig = icAppSpec.fCreator;
  358.                 helperInfo.versionNumber = 0;
  359.                 helperInfo.lastMod = 0;
  360.                 for (p = *gPrefs.urlHelpers; *p->schemeName != 0; p++) {
  361.                     if (MyStrEqual(schemeName, p->schemeName)) {
  362.                         if (helperInfo.sig == p->sig) {
  363.                             helperInfo.versionNumber = p->versionNumber;
  364.                             helperInfo.lastMod = p->lastMod;
  365.                         } 
  366.                         break;
  367.                     }
  368.                 }
  369.                 hSize += sizeof(TURLHelperInfo);
  370.                 err = MySetHandleSize(h, hSize);
  371.                 if (err != noErr) goto exit;
  372.                 (*h)[numHelpers] = helperInfo;
  373.                 numHelpers++;
  374.             }
  375.         }
  376.     }
  377.     
  378.     hSize += sizeof(TURLHelperInfo);
  379.     err = MySetHandleSize(h, hSize);
  380.     memset(*h + numHelpers, 0, sizeof(TURLHelperInfo));
  381.     
  382.     MyDisposeHandle(gPrefs.urlHelpers);
  383.     gPrefs.urlHelpers = h;
  384.     
  385.     return;
  386.     
  387. exit:
  388.  
  389.     MyDisposeHandle(h);
  390.     return;
  391. }
  392.  
  393.  
  394.  
  395. /*----------------------------------------------------------------------------
  396.     ReadEditorInfo 
  397.     
  398.     Read text editor info from an ICAppSpec IC pref.
  399.             
  400.     Exit:    *sig = signature of editor applicaton.
  401. ----------------------------------------------------------------------------*/
  402.  
  403. static void ReadEditorInfo (OSType *sig)
  404. {
  405.     ICError icErr;
  406.     ICAppSpec icAppSpec;
  407.     ICAttr attr;
  408.     long size;
  409.     
  410.     size = sizeof(icAppSpec);
  411.     icErr = MyICGetPref(gInst, kICeditorHelper, &attr, (Ptr)&icAppSpec, &size);
  412.     if (icErr == noErr) *sig = icAppSpec.fCreator;
  413. }
  414.  
  415.  
  416.  
  417. /*----------------------------------------------------------------------------
  418.     MyICReadURLHelperPref 
  419.     
  420.     Read a URL helper program Internet Config pref.
  421.     
  422.     Entry:    schemeName = URL scheme name.
  423. ----------------------------------------------------------------------------*/
  424.  
  425. void MyICReadURLHelperPref (TURLSchemeName schemeName)
  426. {
  427.     ICError icErr;
  428.     Str255 key;
  429.     short len;
  430.     ICAppSpec icAppSpec;
  431.     ICAttr attr;
  432.     long size;
  433.     short i;
  434.     TURLHelperInfo *p;
  435.     OSErr err = noErr;
  436.  
  437.     if (!gICStartOK) return;
  438.     
  439.     icErr = ICBegin(gInst, icReadOnlyPerm);
  440.     if (icErr != noErr) return;
  441.     
  442.     CopyPascalString(key, kICHelper);
  443.     len = strlen(schemeName);
  444.     BlockMoveData(schemeName, key + *key + 1, len);
  445.     *key += len;
  446.     
  447.     size = sizeof(icAppSpec);
  448.     icErr = MyICGetPref(gInst, key, &attr, (Ptr)&icAppSpec, &size);
  449.     if (icErr != noErr && icErr != icPrefNotFoundErr) goto exit;
  450.     
  451.     for (i = 0, p = *gPrefs.urlHelpers; *p->schemeName != 0; i++, p++) {
  452.         if (MyStrEqual(schemeName, p->schemeName)) break;
  453.     }
  454.     
  455.     if (icErr == noErr) {
  456.         if (*p->schemeName == 0) {
  457.             /* IC has this scheme, but NW does not. Add the new scheme to the end of
  458.                the gPrefs.urlHelpers array. */
  459.             size = MyGetHandleSize(gPrefs.urlHelpers);
  460.             err = MySetHandleSize(gPrefs.urlHelpers, size + sizeof(TURLHelperInfo));
  461.             if (err != noErr) goto exit;
  462.             p = &(*gPrefs.urlHelpers)[i];
  463.             strcpy(p->schemeName, schemeName);
  464.             p->sig = icAppSpec.fCreator;
  465.             p->versionNumber = 0;
  466.             p->lastMod = 0;
  467.             memset(p+1, 0, sizeof(TURLHelperInfo));
  468.         } else {
  469.             /* Both IC and NW have this scheme. Update the info for this helper in
  470.                the gPrefs.urlHelpers array. */
  471.             if (icAppSpec.fCreator == p->sig) goto exit;
  472.             p->sig = icAppSpec.fCreator;
  473.             p->versionNumber = 0;
  474.             p->lastMod = 0;
  475.         }
  476.     } else {
  477.         if (*p->schemeName == 0) {
  478.             /* IC does not have this scheme, and neither does NW. Just return. */
  479.             goto exit;
  480.         } else {
  481.             /* IC does not have this scheme, but NW does. Delete it from the 
  482.                gPrefs.urlHelpers array. */
  483.             size = MyGetHandleSize(gPrefs.urlHelpers);
  484.             BlockMoveData(
  485.                 *gPrefs.urlHelpers + i + 1,
  486.                 *gPrefs.urlHelpers + i,
  487.                 size - (i+1) * sizeof(TURLHelperInfo));
  488.             MySetHandleSize(gPrefs.urlHelpers, size - sizeof(TURLHelperInfo));
  489.         }
  490.     }
  491.     
  492. exit:
  493.  
  494.     ICEnd(gInst);
  495. }
  496.     
  497.  
  498.  
  499. /*----------------------------------------------------------------------------
  500.     MyICReadSharedPrefs 
  501.     
  502.     Read shared Internet Config prefs.
  503.     
  504.     Entry:    key = IC keyword for shared pref.
  505. ----------------------------------------------------------------------------*/
  506.  
  507. void MyICReadSharedPrefs (ConstStr255Param key)
  508. {
  509.     ICError icErr;
  510.  
  511.     if (!gICStartOK) return;
  512.     
  513.     icErr = ICBegin(gInst, icReadOnlyPerm);
  514.     if (icErr != noErr) return;
  515.     
  516.     if (EqualString(key, kICAllSharedPrefs, true, true)) {
  517.         ReadCStringFromPString(gPrefs.fullName, sizeof(gPrefs.fullName), 
  518.             kICRealName);
  519.         ReadCStringFromPString(gPrefs.organization, sizeof(gPrefs.organization),
  520.             kICOrganization);
  521.         ReadCStringFromPString(gPrefs.quoteString, sizeof(gPrefs.quoteString),
  522.             kICQuotingString);
  523.         ReadCStringFromText(gPrefs.signature, sizeof(gPrefs.signature),
  524.             kICSignature);
  525.         ReadCStringFromPString(gPrefs.emailAddress, sizeof(gPrefs.emailAddress),
  526.             kICEmail);
  527.         ReadPStringFromPString(gPrefs.mailServerName, sizeof(gPrefs.mailServerName),
  528.             kICSMTPHost);
  529.         ReadCStringFromText(gPrefs.extraMailHdrLines, sizeof(gPrefs.extraMailHdrLines),
  530.             kICMailHeaders);
  531.         ReadCStringFromPString(gPrefs.authUsername, sizeof(gPrefs.authUsername),
  532.             kICNewsAuthUsername);
  533.         ReadCStringFromPString(gPrefs.authPassword, sizeof(gPrefs.authPassword),
  534.             kICNewsAuthPassword);
  535.         ReadPStringFromPString(gPrefs.newsServerName, sizeof(gPrefs.newsServerName),
  536.             kICNNTPHost);
  537.         ReadCStringFromText(gPrefs.extraNewsHdrLines, sizeof(gPrefs.extraNewsHdrLines),
  538.             kICNewsHeaders);
  539.         ReadFolderFromFileSpec(&gPrefs.savedBinDefaultFolderAlias, kICDownloadFolder);
  540.         ReadFontInfo(gPrefs.textFont, &gPrefs.textSize, kICScreenFont);
  541.         ReadFontInfo(gPrefs.listFont, &gPrefs.listSize, kICListFont);
  542.         ReadFontInfo(gPrefs.printingFont, &gPrefs.printingSize, kICPrinterFont);
  543.         ReadURLHelperInfo();
  544.         ReadEditorInfo(&gPrefs.savedArtCreator);
  545.     } else if (EqualString(key, kICRealName, true, true)) {
  546.         ReadCStringFromPString(gPrefs.fullName, sizeof(gPrefs.fullName), 
  547.             kICRealName);
  548.     } else if (EqualString(key, kICOrganization, true, true)) {
  549.         ReadCStringFromPString(gPrefs.organization, sizeof(gPrefs.organization),
  550.             kICOrganization);
  551.     } else if (EqualString(key, kICQuotingString, true, true)) {
  552.         ReadCStringFromPString(gPrefs.quoteString, sizeof(gPrefs.quoteString),
  553.             kICQuotingString);
  554.     } else if (EqualString(key, kICSignature, true, true)) {
  555.         ReadCStringFromText(gPrefs.signature, sizeof(gPrefs.signature),
  556.             kICSignature);
  557.     } else if (EqualString(key, kICEmail, true, true)) {
  558.         ReadCStringFromPString(gPrefs.emailAddress, sizeof(gPrefs.emailAddress),
  559.             kICEmail);
  560.     } else if (EqualString(key, kICSMTPHost, true, true)) {
  561.         ReadPStringFromPString(gPrefs.mailServerName, sizeof(gPrefs.mailServerName),
  562.             kICSMTPHost);
  563.     } else if (EqualString(key, kICMailHeaders, true, true)) {
  564.         ReadCStringFromText(gPrefs.extraMailHdrLines, sizeof(gPrefs.extraMailHdrLines),
  565.             kICMailHeaders);
  566.     } else if (EqualString(key, kICNewsAuthUsername, true, true)) {
  567.         ReadCStringFromPString(gPrefs.authUsername, sizeof(gPrefs.authUsername),
  568.             kICNewsAuthUsername);
  569.     } else if (EqualString(key, kICNewsAuthPassword, true, true)) {
  570.         ReadCStringFromPString(gPrefs.authPassword, sizeof(gPrefs.authPassword),
  571.             kICNewsAuthPassword);
  572.     } else if (EqualString(key, kICNNTPHost, true, true)) {
  573.         ReadPStringFromPString(gPrefs.newsServerName, sizeof(gPrefs.newsServerName),
  574.             kICNNTPHost);
  575.     } else if (EqualString(key, kICNewsHeaders, true, true)) {
  576.         ReadCStringFromText(gPrefs.extraNewsHdrLines, sizeof(gPrefs.extraNewsHdrLines),
  577.             kICNewsHeaders);
  578.     } else if (EqualString(key, kICDownloadFolder, true, true)) {
  579.         ReadFolderFromFileSpec(&gPrefs.savedBinDefaultFolderAlias, kICDownloadFolder);
  580.     } else if (EqualString(key, kICScreenFont, true, true)) {
  581.         ReadFontInfo(gPrefs.textFont, &gPrefs.textSize, kICScreenFont);
  582.     } else if (EqualString(key, kICListFont, true, true)) {
  583.         ReadFontInfo(gPrefs.listFont, &gPrefs.listSize, kICListFont);
  584.     } else if (EqualString(key, kICPrinterFont, true, true)) {
  585.         ReadFontInfo(gPrefs.printingFont, &gPrefs.printingSize, kICPrinterFont);
  586.     } else if (EqualString(key, kICeditorHelper, true, true)) {
  587.         ReadEditorInfo(&gPrefs.savedArtCreator);
  588.     }
  589.     
  590.     ICEnd(gInst);
  591. }
  592.  
  593.  
  594.  
  595. /*----------------------------------------------------------------------------
  596.     WriteCStringToPString 
  597.     
  598.     Write a C string shared pref to a P string IC pref.
  599.     
  600.     Entry:    theString = pointer to C string shared pref.
  601.             key = IC keyword.
  602. ----------------------------------------------------------------------------*/
  603.  
  604. static void WriteCStringToPString (char *theString, ConstStr255Param key)
  605. {
  606.     CStr255 str;
  607.     
  608.     strcpy(str, theString);
  609.     if (EqualString(key, kICNewsAuthPassword, true, true)) {
  610.         if (!gPrefs.authSavePassword) return;
  611.         ScramblePassword(str);
  612.     }
  613.     c2pstr(str);
  614.     MyICSetPref(gInst, key, ICattr_no_change, (Ptr)str, *str+1); 
  615. }
  616.  
  617.  
  618.  
  619. /*----------------------------------------------------------------------------
  620.     WritePStringToPString 
  621.     
  622.     Write a P string shared pref to a P string IC pref.
  623.     
  624.     Entry:    theString = pointer to P string shared pref.
  625.             key = IC keyword.
  626. ----------------------------------------------------------------------------*/
  627.  
  628. static void WritePStringToPString (StringPtr theString, ConstStr255Param key)
  629. {
  630.     MyICSetPref(gInst, key, ICattr_no_change, (Ptr)theString, *theString+1); 
  631. }
  632.  
  633.  
  634.  
  635. /*----------------------------------------------------------------------------
  636.     WriteCStringToText 
  637.     
  638.     Write a C string shared pref to a text IC pref.
  639.     
  640.     Entry:    theString = pointer to C string shared pref.
  641.             key = IC keyword.
  642. ----------------------------------------------------------------------------*/
  643.  
  644. static void WriteCStringToText (char *theString, ConstStr255Param key)
  645. {
  646.     MyICSetPref(gInst, key, ICattr_no_change, (Ptr)theString, strlen(theString));
  647. }
  648.  
  649.  
  650.  
  651. /*----------------------------------------------------------------------------
  652.     WriteFolderToFileSpec 
  653.     
  654.     Write a default folder shared pref to an ICFileSpec IC pref.
  655.     
  656.     Entry:    defaultFolderAlias = Handle to alias for default folder
  657.             key = IC keyword.
  658. ----------------------------------------------------------------------------*/
  659.  
  660. static void WriteFolderToFileSpec (AliasHandle defaultFolderAlias, 
  661.     ConstStr255Param key)
  662. {
  663.     char buf[4096];
  664.     OSErr err = noErr;
  665.     ICFileSpec *p;
  666.     HParamBlockRec pb;
  667.     Str31 volName;
  668.     long aliasSize, size;
  669.     FSSpec fss;
  670.     Boolean wasChanged;
  671.     
  672.     if (defaultFolderAlias == nil) return;
  673.     err = ResolveAlias(nil, defaultFolderAlias, &fss, &wasChanged); 
  674.     if (err != noErr) return;
  675.     pb.volumeParam.ioNamePtr = volName;
  676.     pb.volumeParam.ioVolIndex = 0;
  677.     pb.volumeParam.ioVRefNum = fss.vRefNum;
  678.     err = PBHGetVInfoSync(&pb);
  679.     p = (ICFileSpec*)buf;
  680.     CopyPascalString(p->vol_name, volName);
  681.     p->vol_creation_date = pb.volumeParam.ioVCrDate;
  682.     p->fss = fss;
  683.     aliasSize = (**defaultFolderAlias).aliasSize;
  684.     size = aliasSize + sizeof(Str31) + sizeof(long) + sizeof(FSSpec);
  685.     if (size > sizeof(buf)) return;
  686.     BlockMoveData(*defaultFolderAlias, &p->alias, aliasSize);
  687.     MyICSetPref(gInst, key, ICattr_no_change, (Ptr)buf, size);
  688. }
  689.  
  690.  
  691.  
  692. /*----------------------------------------------------------------------------
  693.     WriteFontInfo 
  694.     
  695.     Read font info to an ICFontRecord IC pref.
  696.     
  697.     Entry:    fontName = font name.
  698.             fontSize = font size.
  699.             key = IC keyword.
  700. ----------------------------------------------------------------------------*/
  701.  
  702. static void WriteFontInfo (Str255 fontName, short fontSize, 
  703.     ConstStr255Param key)
  704. {
  705.     ICError icErr;
  706.     ICFontRecord icFontRecord;
  707.     ICAttr attr;
  708.     long size;
  709.  
  710.     size = sizeof(icFontRecord);
  711.     icErr = MyICGetPref(gInst, key, &attr, (Ptr)&icFontRecord, &size);
  712.     if (icErr == icPrefNotFoundErr) {
  713.         icFontRecord.face = normal;
  714.     } else if (icErr != noErr) {
  715.         return;
  716.     }
  717.     CopyPascalString(icFontRecord.font, fontName);
  718.     icFontRecord.size = fontSize;
  719.     MyICSetPref(gInst, key, ICattr_no_change, (Ptr)&icFontRecord, sizeof(icFontRecord));
  720. }
  721.  
  722.  
  723.  
  724. /*----------------------------------------------------------------------------
  725.     WriteURLHelperInfo 
  726.     
  727.     Write URL Helper info.
  728. ----------------------------------------------------------------------------*/
  729.  
  730. static void WriteURLHelperInfo (void)
  731. {
  732.     ICError icErr;
  733.     Str255 key;
  734.     long i, count;
  735.     short prefixLen, schemeNameLen;
  736.     TURLSchemeName schemeName;
  737.     TURLHelperInfo *p;
  738.     Str255 **keysToDelete = nil;
  739.     short numKeysToDelete = 0;
  740.     OSErr err = noErr;
  741.     TURLHelperInfo helperInfo;
  742.     ICAppSpec icAppSpec;
  743.     
  744.     err = MyNewHandle(0, &keysToDelete);
  745.     if (err != noErr) goto exit;
  746.     
  747.     prefixLen = *kICHelper;
  748.     
  749.     icErr = ICCountPref(gInst, &count);
  750.     if (icErr != noErr) goto exit;
  751.     
  752.     for (i = 1; i <= count; i++) {
  753.         icErr = ICGetIndPref(gInst, i, key);
  754.         if (icErr != noErr) goto exit;
  755.         schemeNameLen = *key - prefixLen;
  756.         if (schemeNameLen > 0 && schemeNameLen <= kMaxSchemeNameLen && 
  757.             MyStrNEqual((char*)key+1, (char*)kICHelper+1, prefixLen)) 
  758.         {
  759.             BlockMoveData(key + prefixLen + 1, schemeName, schemeNameLen);
  760.             schemeName[schemeNameLen] = 0;
  761.             if (!MyStrEqual(schemeName, "editor") && !MyStrEqual(schemeName, "mailto") &&
  762.                 !MyStrEqual(schemeName, "nntp") && !MyStrEqual(schemeName, "news"))
  763.             {
  764.                 for (p = *gPrefs.urlHelpers; *p->schemeName != 0; p++) {
  765.                     if (MyStrEqual(schemeName, p->schemeName)) break;
  766.                 }
  767.                 if (*p->schemeName == 0) {
  768.                     numKeysToDelete++;
  769.                     err = MySetHandleSize(keysToDelete, numKeysToDelete * sizeof(Str255));
  770.                     if (err != noErr) goto exit;
  771.                     BlockMoveData(key, *keysToDelete + numKeysToDelete - 1, sizeof(Str255));
  772.                 }
  773.             }
  774.         }
  775.     }
  776.     
  777.     for (i = 0; i < numKeysToDelete; i++) {
  778.         BlockMoveData(*keysToDelete + i, key, sizeof(Str255));
  779.         ICDeletePref(gInst, key);
  780.     }
  781.     
  782.     for (i = 0; ; i++) {
  783.         helperInfo = (*gPrefs.urlHelpers)[i];
  784.         if (*helperInfo.schemeName == 0) break;
  785.         CopyPascalString(key, kICHelper);
  786.         schemeNameLen = strlen(helperInfo.schemeName);
  787.         BlockMoveData(helperInfo.schemeName, key + prefixLen + 1, schemeNameLen);
  788.         *key += schemeNameLen;
  789.         icAppSpec.fCreator = helperInfo.sig;
  790.         *icAppSpec.name = 0;
  791.         FindAppNameFromSig(helperInfo.sig, icAppSpec.name);
  792.         MyICSetPref(gInst, key, ICattr_no_change, (Ptr)&icAppSpec, sizeof(icAppSpec));
  793.     }
  794.  
  795. exit:
  796.     
  797.     MyDisposeHandle(keysToDelete);
  798.  
  799. }
  800.  
  801.  
  802.  
  803. /*----------------------------------------------------------------------------
  804.     WriteEditorInfo 
  805.     
  806.     Write Editor info to the "editor" helper ICAppSpec IC pref.
  807.     
  808.     Entry:    sig = editor helper signature.
  809. ----------------------------------------------------------------------------*/
  810.  
  811. static void WriteEditorInfo (OSType sig)
  812. {
  813.     ICAppSpec icAppSpec;
  814.     long size;
  815.     OSErr err = noErr;
  816.     
  817.     icAppSpec.fCreator = sig;
  818.     err = FindAppNameFromSig(sig, icAppSpec.name);
  819.     if (err != noErr) *icAppSpec.name = 0;
  820.     size = sizeof(icAppSpec);
  821.     MyICSetPref(gInst, kICeditorHelper, ICattr_no_change, (Ptr)&icAppSpec, size);
  822. }
  823.  
  824.  
  825.  
  826. /*----------------------------------------------------------------------------
  827.     MyICWriteSharedPrefs 
  828.     
  829.     Write shared Internet Config prefs.
  830.     
  831.     Entry:    key = IC keyword for shared pref.
  832. ----------------------------------------------------------------------------*/
  833.  
  834. void MyICWriteSharedPrefs (ConstStr255Param key)
  835. {
  836.     ICError icErr;
  837.  
  838.     if (!gICStartOK) return;
  839.     
  840.     icErr = ICBegin(gInst, icReadWritePerm);
  841.     if (icErr != noErr) return;
  842.     
  843.     if (EqualString(key, kICAllSharedPrefs, true, true)) {
  844.         WriteCStringToPString(gPrefs.fullName, kICRealName);
  845.         WriteCStringToPString(gPrefs.organization, kICOrganization);
  846.         WriteCStringToPString(gPrefs.quoteString, kICQuotingString);
  847.         WriteCStringToText(gPrefs.signature, kICSignature);
  848.         WriteCStringToPString(gPrefs.emailAddress, kICEmail);
  849.         WritePStringToPString(gPrefs.mailServerName, kICSMTPHost);
  850.         WriteCStringToText(gPrefs.extraMailHdrLines, kICMailHeaders);
  851.         WriteCStringToPString(gPrefs.authUsername, kICNewsAuthUsername);
  852.         WriteCStringToPString(gPrefs.authPassword, kICNewsAuthPassword);
  853.         WritePStringToPString(gPrefs.newsServerName, kICNNTPHost);
  854.         WriteCStringToText(gPrefs.extraNewsHdrLines, kICNewsHeaders);
  855.         WriteFolderToFileSpec(gPrefs.savedBinDefaultFolderAlias, kICDownloadFolder); 
  856.         WriteFontInfo(gPrefs.textFont, gPrefs.textSize, kICScreenFont);
  857.         WriteFontInfo(gPrefs.listFont, gPrefs.listSize, kICListFont);
  858.         WriteFontInfo(gPrefs.printingFont, gPrefs.printingSize, kICPrinterFont);
  859.         WriteURLHelperInfo();
  860.         WriteEditorInfo(gPrefs.savedArtCreator);
  861.     } else if (EqualString(key, kICRealName, true, true)) {
  862.         WriteCStringToPString(gPrefs.fullName, kICRealName);
  863.     } else if (EqualString(key, kICOrganization, true, true)) {
  864.         WriteCStringToPString(gPrefs.organization, kICOrganization);
  865.     } else if (EqualString(key, kICQuotingString, true, true)) {
  866.         WriteCStringToPString(gPrefs.quoteString, kICQuotingString);
  867.     } else if (EqualString(key, kICSignature, true, true)) {
  868.         WriteCStringToText(gPrefs.signature, kICSignature);
  869.     } else if (EqualString(key, kICEmail, true, true)) {
  870.         WriteCStringToPString(gPrefs.emailAddress, kICEmail);
  871.     } else if (EqualString(key, kICSMTPHost, true, true)) {
  872.         WritePStringToPString(gPrefs.mailServerName, kICSMTPHost);
  873.     } else if (EqualString(key, kICMailHeaders, true, true)) {
  874.         WriteCStringToText(gPrefs.extraMailHdrLines, kICMailHeaders);
  875.     } else if (EqualString(key, kICNewsAuthUsername, true, true)) {
  876.         WriteCStringToPString(gPrefs.authUsername, kICNewsAuthUsername);
  877.     } else if (EqualString(key, kICNewsAuthPassword, true, true)) {
  878.         WriteCStringToPString(gPrefs.authPassword, kICNewsAuthPassword);
  879.     } else if (EqualString(key, kICNNTPHost, true, true)) {
  880.         WritePStringToPString(gPrefs.newsServerName, kICNNTPHost);
  881.     } else if (EqualString(key, kICNewsHeaders, true, true)) {
  882.         WriteCStringToText(gPrefs.extraNewsHdrLines, kICNewsHeaders);
  883.     } else if (EqualString(key, kICDownloadFolder, true, true)) {
  884.         WriteFolderToFileSpec(gPrefs.savedBinDefaultFolderAlias, kICDownloadFolder); 
  885.     } else if (EqualString(key, kICScreenFont, true, true)) {
  886.         WriteFontInfo(gPrefs.textFont, gPrefs.textSize, kICScreenFont);
  887.     } else if (EqualString(key, kICListFont, true, true)) {
  888.         WriteFontInfo(gPrefs.listFont, gPrefs.listSize, kICListFont);
  889.     } else if (EqualString(key, kICPrinterFont, true, true)) {
  890.         WriteFontInfo(gPrefs.printingFont, gPrefs.printingSize, kICPrinterFont);
  891.     } else if (EqualString(key, kICeditorHelper, true, true)) {
  892.         WriteEditorInfo(gPrefs.savedArtCreator);
  893.     }
  894.     
  895.     ICEnd(gInst);
  896. }
  897.